/**
 * Copyright (c) 2020 lizebang
 *
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

package jiri

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"gitee.com/banggua/ggtsync/cmdutil/gitutil"
	"gitee.com/banggua/ggtsync/config"
	"gitee.com/banggua/ggtsync/logger"
)

func read(path string) (string, error) {
	file, err := os.OpenFile(path, os.O_RDONLY, 0644)
	if err != nil {
		return "", err
	}
	defer file.Close()

	b, err := ioutil.ReadAll(file)
	return string(b), err
}

func write(path string, str string) (int, error) {
	file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		return 0, err
	}
	defer file.Close()

	return file.WriteString(str)
}

func (jc *jiriClient) jiriImportReplace(project *config.Project) error {
	var (
		_, _, remoteURL, _ = getArgs(project.From)
		baseurl            = project.Args["baseurl"]
		manifest           = project.Args["manifest"]
		savepath           = filepath.Join(project.To, manifest)
		username           = project.Args["username"]
		useremail          = project.Args["useremail"]
	)

	err := os.RemoveAll(savepath)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	err = gitutil.Clone("", remoteURL, savepath)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	err = os.RemoveAll(filepath.Join(savepath, ".git"))
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}

	re, err := regexp.Compile(`remote=".*"`)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	modify := func(path string) error {
		str, err := read(path)
		if err != nil && os.IsNotExist(err) {
			return nil
		}
		if err != nil {
			return err
		}
		_, err = write(path, re.ReplaceAllStringFunc(str, func(src string) string {
			tmp := src[len(`remote="`) : len(src)-1]
			if tmp == remoteURL {
				return `remote="` + baseurl + "/" + manifest + `"`
			}
			tmp, err := projectRemoteURL(baseurl, tmp)
			if err != nil {
				logger.Errorf("%s %v", str, err)
				return str
			}
			return `remote="` + tmp + `"`
		}))
		return err
	}
	err = filepath.Walk(savepath,
		func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}
			if strings.Contains(path, ".git") {
				return nil
			}
			if !info.IsDir() {
				return modify(path)
			}
			return nil
		},
	)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}

	err = gitutil.Init(savepath)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	err = gitutil.Config(savepath, "user.name", username)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	err = gitutil.Config(savepath, "user.email", useremail)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	err = gitutil.Add(savepath, "--all")
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	err = gitutil.Commit(savepath, project.Name)
	if err != nil {
		logger.Errorf("%v %v", project, err)
		return err
	}
	return nil
}
